package com.uls.hj.service.impl;

import java.text.SimpleDateFormat;
import java.util.*;

import com.uls.common.core.domain.AjaxResult;
import com.uls.common.core.domain.entity.SysUser;
import com.uls.common.utils.DateUtils;
import com.uls.hj.domain.HjMessages;
import com.uls.hj.domain.HjVenueSchedules;
import com.uls.hj.domain.HjVenues;
import com.uls.hj.mapper.HjVenueSchedulesMapper;
import com.uls.hj.service.IHjMessagesService;
import com.uls.hj.service.IHjVenuesService;
import com.uls.hj.vo.TaskCommentVo;
import com.uls.system.service.ISysUserService;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.identity.Authentication;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.uls.hj.mapper.HjBookingsMapper;
import com.uls.hj.domain.HjBookings;
import com.uls.hj.service.IHjBookingsService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 预订Service业务层处理
 * 
 * @author hj
 * @date 2024-11-09
 */
@Service
public class HjBookingsServiceImpl implements IHjBookingsService 
{
    @Autowired
    private HjBookingsMapper hjBookingsMapper;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private HistoryService historyService;

    @Autowired
    private HjVenueSchedulesMapper hjVenueSchedulesMapper;

    @Autowired
    private IHjVenuesService hjVenuesService;

    @Autowired
    private IHjMessagesService hjMessagesService;

    /**
     * 查询预订
     * 
     * @param bookingId 预订主键
     * @return 预订
     */
    @Override
    public HjBookings selectHjBookingsByBookingId(Long bookingId)
    {
        return hjBookingsMapper.selectHjBookingsByBookingId(bookingId);
    }

    /**
     * 查询预订列表
     * 
     * @param hjBookings 预订
     * @return 预订
     */
    @Override
    public List<HjBookings> selectHjBookingsList(HjBookings hjBookings)
    {
        return hjBookingsMapper.selectHjBookingsList(hjBookings);
    }

    /**
     * 新增预订
     * 
     * @param hjBookings 预订
     * @return 结果
     */
    @Override
    public int insertHjBookings(HjBookings hjBookings)
    {
        hjBookings.setCreateTime(DateUtils.getNowDate());
        return hjBookingsMapper.insertHjBookings(hjBookings);
    }

    /**
     * 修改预订
     * 
     * @param hjBookings 预订
     * @return 结果
     */
    @Override
    public int updateHjBookings(HjBookings hjBookings)
    {
        hjBookings.setUpdateTime(DateUtils.getNowDate());
        return hjBookingsMapper.updateHjBookings(hjBookings);
    }

    /**
     * 批量删除预订
     * 
     * @param bookingIds 需要删除的预订主键
     * @return 结果
     */
    @Override
    public int deleteHjBookingsByBookingIds(Long[] bookingIds)
    {
        return hjBookingsMapper.deleteHjBookingsByBookingIds(bookingIds);
    }

    /**
     * 删除预订信息
     * 
     * @param bookingId 预订主键
     * @return 结果
     */
    @Override
    public int deleteHjBookingsByBookingId(Long bookingId)
    {
        return hjBookingsMapper.deleteHjBookingsByBookingId(bookingId);
    }

    @Override
    public int updateHjBookingsByBookingId(Map<String, Object> params) {
        return hjBookingsMapper.updateHjBookingsByBookingId(params);
    }

    @Override
    public int updateHjBookingsByBookingIds(Map<String, Object> params) {
        return hjBookingsMapper.updateHjBookingsByBookingIds(params);
    }


    /**
     * 启动流程
     * @param bookingId
     * @param userId
     */
    @Override
    @Transactional
    public int submit(Long bookingId, Long userId) {
        HjBookings hjBooking=hjBookingsMapper.selectHjBookingsByBookingId(bookingId);

        String processDefiKey ="bookingProcess";
        Map<String, Object> variables = new HashMap<String,Object>();
        variables.put("inputUser1",userId);
        variables.put("inputUser2",132);  //先写死，是管理员（小赵）的编号
        //没有启动这个流程
        if (hjBooking.getBookingStatus()==0) {
            ProcessInstance pi = runtimeService.startProcessInstanceByKey(processDefiKey, variables);
            hjBooking.setFlowInstantId(Long.parseLong(pi.getProcessInstanceId()));  // 把流程实例id与业务系统绑定
            hjBooking.setBookingStatus(1L);//预订状态(0-待提交、1-审核中、2-已打回、3-已通过)
            TaskQuery taskQuery = taskService.createTaskQuery();
            // 办理人的任务列表
            List<Task> list = taskQuery
                    .taskAssignee(""+userId)
                    .processInstanceId(pi.getProcessInstanceId())
                    .list();
            Task task=list.get(0);
            taskService.complete(task.getId());

            return  hjBookingsMapper.updateHjBookings(hjBooking);
        }
        //流程启动了，打回重新审批，就不用再启动流程
        else{

            Long flowInstantId=hjBooking.getFlowInstantId();
            TaskQuery taskQuery = taskService.createTaskQuery();
            // 办理人的任务列表
            List<Task> list = taskQuery
                    .processInstanceId("" + flowInstantId)
                    .list();
            Task task=list.get(0);
            taskService.complete(task.getId());
            hjBooking.setBookingStatus(1L);//预订状态(0-待提交、1-审核中、2-已打回、3-已通过)
            return  hjBookingsMapper.updateHjBookings(hjBooking);
        }
    }

    /**
     * 未完成的任务所对应的预约数据和各种条件查询
     * @param userId
     * @param processDefiniionKey
     * @param booking
     * @return
     */
    @Override
    @Transactional
    public List<HjBookings> noFinishTask(Long userId,String processDefiniionKey,HjBookings booking) {
        List<HjBookings> listBookings=new ArrayList<HjBookings>();
        // 创建一个任务查询对象
        TaskQuery taskQuery = taskService.createTaskQuery();
        // 办理人的任务列表
        List<Task> list = taskQuery
                .taskAssignee(""+userId)
                .processDefinitionKey(processDefiniionKey)
                .list();
        // 遍历任务列表
        if (list != null && list.size() > 0) {
            for (Task task : list) {
                if (!task.getName().equals("填写预约信息")) {
                    Long flowInstanceId = Long.parseLong(task.getProcessInstanceId());
                    booking.setFlowInstantId(flowInstanceId);
                    //根据流程id和其他条件查询老师mapper的方法
                    HjBookings booking1 = hjBookingsMapper.selectBookingFlowIdOther(booking);
                    if (booking1!=null)
                        listBookings.add(booking1);
                }

            }
        }

        return listBookings;
    }

    /**
     * 完成任务
     * @param flowInstantId
     */
    @Override
    @Transactional
    public void completeTask(Long flowInstantId, Integer agree, Long userId, String comment, Long bookingId) {
        HjBookings booking=hjBookingsMapper.selectHjBookingsByBookingId(bookingId);

        TaskQuery taskQuery = taskService.createTaskQuery();
        // 办理人的任务列表
        List<Task> list = taskQuery
                .processInstanceId("" + flowInstantId)
                .list();
        // 遍历任务列表
        Map<String, Object> params = new HashMap<String, Object>();

        if (list != null && list.size() > 0) {
            for (Task task : list) {

                if (task.getName().equals("管理员审批")){
                    if (agree==1){
                        params.put("inputUser3", 133);  //固定一个人员4
                        booking.setBookingStatus(1L);//预订状态(0-待提交、1-审核中、2-已打回、3-已通过)
                    }else {
                        booking.setBookingStatus(2L);
                        messageNo(comment,bookingId);
                    }
                    params.put("pass1", agree);  //给流程变量赋值

                }else if (task.getName().equals("副主任审批")){
                    if (agree==1){
                        params.put("inputUser4", 134);
                        booking.setBookingStatus(1L);
                    }
                    else {
                        booking.setBookingStatus(2L);
                        messageNo(comment,bookingId);
                    }
                    params.put("pass2", agree);  //给流程变量赋值
                }else if (task.getName().equals("主任审批")){
                    if (agree==1){
                        booking.setBookingStatus(3L);
                        //加事务
                        HjVenueSchedules venueSchedules = new HjVenueSchedules();
                        venueSchedules.setBookingId(bookingId);
                        venueSchedules.setVenueId(booking.getVenueId());
                        venueSchedules.setScheduleDate(booking.getBookingDate());
                        venueSchedules.setUseTime(booking.getBookingTime());
                        venueSchedules.setCreateTime(new Date());

                        hjVenueSchedulesMapper.insertHjVenueSchedules(venueSchedules);

                        message(bookingId);

                    }
                    else {
                        booking.setBookingStatus(2L);
                        messageNo(comment,bookingId);
                    }
                    params.put("pass3", agree);  //给流程变量赋值
                }


                hjBookingsMapper.updateHjBookings(booking);

                // 添加批注时候的审核人，通常应该从session获取,现在从redis
                Authentication.setAuthenticatedUserId(userId.toString());
                // 添加批注
                taskService.addComment(task.getId(), task.getProcessInstanceId(), comment);
                // taskId：任务id
                taskService.complete(task.getId(), params);

            }
        }

    }

    private void messageNo(String comment, Long bookingId){
        HjBookings hjBookings = selectHjBookingsByBookingId(bookingId);

        String bookingTime = hjBookings.getBookingTime();
        String bookingTimeString = "";
        if (bookingTime.equals("0")){
            bookingTimeString = "8:00~11:00";
        }else if (bookingTime.equals("1")){
            bookingTimeString = "13:00~16:00";
        }else if (bookingTime.equals("2")){
            bookingTimeString = "16:00~19:00";
        }

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String bookingDateString = dateFormat.format(hjBookings.getBookingDate());

        HjMessages messages = new HjMessages();
        messages.setReceiverId(hjBookings.getUserId());
        messages.setMessageType(1L);
        HjVenues venues = hjVenuesService.selectHjVenuesByVenueId(hjBookings.getVenueId());
        messages.setMessageContent("您的预约被打回！！  您的预约信息： [" + venues.getVenueName() +
                "," + bookingDateString + "," + bookingTimeString + "] 已被打回，原因为： " + comment);
        hjMessagesService.insertHjMessages(messages);
    }

    private void message(Long bookingId){
        HjBookings hjBookings = selectHjBookingsByBookingId(bookingId);

        String bookingTime = hjBookings.getBookingTime();
        String bookingTimeString = "";
        if (bookingTime.equals("0")){
            bookingTimeString = "8:00~11:00";
        }else if (bookingTime.equals("1")){
            bookingTimeString = "13:00~16:00";
        }else if (bookingTime.equals("2")){
            bookingTimeString = "16:00~19:00";
        }

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String bookingDateString = dateFormat.format(hjBookings.getBookingDate());

        HjMessages messages = new HjMessages();
        messages.setReceiverId(hjBookings.getUserId());
        messages.setMessageType(1L);
        HjVenues venues = hjVenuesService.selectHjVenuesByVenueId(hjBookings.getVenueId());
        messages.setMessageContent("您的预约已通过！！  您的预约信息： [" + venues.getVenueName() +
                "," + bookingDateString + "," + bookingTimeString + "] ，已通过审批！！");
        hjMessagesService.insertHjMessages(messages);
    }

    //查询审批历史
    @Override
    public List<TaskCommentVo> getTaskCommentList(Long flowInstantId) {

        List<TaskCommentVo> taskCommentVoList=new ArrayList<>();

        List<Comment> list = new ArrayList();

        //从历史批注中取数据
        list = taskService.getProcessInstanceComments(""+flowInstantId);

        for (Comment com : list) {
            TaskCommentVo taskCommentVo=new TaskCommentVo();
            taskCommentVo.setMessage(com.getFullMessage());

            SysUser user=userService.selectUserById(Long.parseLong(com.getUserId()));  //查询用户名

            taskCommentVo.setUserName(user.getNickName());


            //从历史任务取数据
            List<HistoricTaskInstance> hist= historyService.createHistoricTaskInstanceQuery()
                    .processInstanceId(""+flowInstantId)
                    .taskId(com.getTaskId())
                    .list();
            if(hist!=null&&hist.size()>0){
                HistoricTaskInstance historicTaskInstance=hist.get(0);
                taskCommentVo.setTaskKeyId(historicTaskInstance.getTaskDefinitionKey());
                taskCommentVo.setTaskName(historicTaskInstance.getName());
            }

            taskCommentVoList.add(taskCommentVo);

        }


        //排序
        List<TaskCommentVo> taskCommentVoListSort=new ArrayList<>();

        for(int i= taskCommentVoList.size()-1;i>=0;i--)
        {
            TaskCommentVo temp=taskCommentVoList.get(i);
            taskCommentVoListSort.add(temp);
        }

        return taskCommentVoListSort;
    }

    /**
     * 查询完成的任务，任务所对应的学生的数据和各种条件查询
     * @param userId
     * @param processDefiniionKey
     * @return
     */
    @Override
    @Transactional
    public List<HjBookings> finishTask(Long userId, String processDefiniionKey, HjBookings bookings) {
        List<HjBookings> listFinishBookings=new ArrayList<HjBookings>();
        // 创建一个任务查询对象
        //TaskQuery taskQuery = taskService.createTaskQuery();
        // 办理人的任务列表
        List<HistoricTaskInstance> list = historyService
                .createHistoricTaskInstanceQuery()
                .taskAssignee(userId.toString())
                .processDefinitionKey(processDefiniionKey)
                .processFinished()
                .list();
        // 遍历任务列表
        if (list != null && list.size() > 0) {
            for (HistoricTaskInstance temp : list) {
                if (!temp.getName().equals("填写预约信息")) {
                    Long flowInstanceId = Long.parseLong(temp.getProcessInstanceId());
                    bookings.setFlowInstantId(flowInstanceId);
                    //根据流程id查询学生mapper的方法
                    HjBookings booking = hjBookingsMapper.selectBookingFlowIdOther(bookings);
                    if (booking != null){
                        listFinishBookings.add(booking);

                    }

                }

            }
        }

        List<HjBookings> listFinishStudent1 = new ArrayList<>(new HashSet<>(listFinishBookings));
        return listFinishStudent1;
    }


}
